Class Diagram

Class Diagram တစ်ခု ဖန်တီး ဖို့ အတွက် System အကြောင်းကို ဦးစွာ နားလည် ဖို့ လိုပါတယ်။​ လက်ရှိ System က ဘာကို ဖန်တီး ချင်တာလဲ။​ ဘာတွေ လိုအပ်တယ်ဆိုတာကို ဦးစွာ Analysis လုပ်ရပါမယ််။ ပြီးသည့် အခါမှာ လိုအပ်သည့် class တွေကို ခွဲထုတ်ပြီး class diagram ကို ဖန်တီးပါတယ်။ Class တစ်ခု နဲ့ တစ်ခု realtion တွေကို ဖော်ပြသည့် အခါမှာ 

  • Association
  • Dependency
  • Inheritance

စသည် တို့ နဲ့ ဖော်ပြပါတယ်။

Associations

Associations ဆိုတာက class တစ်ခု က နောက်တစ်ခုကို အသုံးပြုထားတယ် ဆိုတာကို ဖော်ပြထားခြင်း ဖြစ်ပါတယ်။

public class Customer {
 private Account checkingAcount;
 public void createNewAccount() {
  checkingAccount = new Account();
 }
}

ဒီ code မှာ Customer class မှာ Account class ကို ယူသုံးထားပါတယ်။ အဲဒီလိုမျိုး code အတွက် class ကို အောက်ပါ အတိုင်း ဆွဲပါတယ်။

One-way associations ဖြစ်သည့် အတွက် Arrow နဲ့ သုံးထားတာကို တွေ့နိုင်ပါတယ်။  A to B သဘောမျိုးပါ။

အကယ်၍ A to B , B to A relation ရှိနေပြီ ဆိုရင်တော့ Arrow မပါတော့ပါဘူး။ ဥပမာ Customer class က Order ကို သုံးမယ်။ Order ထဲမှာလည်း Customer ပါတယ်။ ဒါဆိုရင် Two-way associations ဖြစ်ပါပြီ။

Attributes

Class diagram မှာ properties တွေ ကို Access Modifier ပေါ်မှာ မူတည်ပြီး အနည်းငယ် ပြောင်းလဲ​ဖော်ပြပါတယ်။

public class Customer {
 public String name;
 private String city;
 protected String address;
 private Account account;

 public String getCity() {
  return city;
 }
 
 public void setCity(String newCity) {
  city = newCity;
 }
}

အဲဒီ အခါ class diagram ကို အောက်ပါ အတိုင်း ဆွဲပါတယ်။

  • public ကို +
  • private ကို -
  • protected ကို # 

အနေနဲ့ သုံးပါတယ်။ Account ကတော့ class ဖြစ်သည့် အတွက် direct associations ကို သုံးပါတယ်။

Association ရဲ့ နာမည်တွေဟာ Verb ဖြစ်နေဖို့လိုပါတယ်။ ဥပမာ

  • Professor advises a Student
  • Library has books
  • Student enrolls in a Class

Association Multiplicities

Association မှာ တစ်ခု နဲ့ တစ်ခု ပါဝင် ပတ်သက်မှုကို ဖော်ပြပေးသည့် Multiplicities ဆိုတာ ရှိပါသေးတယ်။

NumberDescription
1One (mandatory)
3Three (exactly)
*Many
0..*zero or more (optional)
1..*one or more
0..1zero or one (optional)

Multiplicities ကို အောက်ပါ အတိုင်း class တွေပါ အသုံးပြုပါတယ်။

ဒီ diagram မှာ ဆိုရင် Multiplicities ရဲ့ အဓိပ္ပာယ်က 

  • Customer တစ်ယောက်မှာ account ၁ ခု သို့မဟုတ် တစ်ခု ထက် မက ရှိတယ်။
  • Account တစ်ခုဟာ Customer တစ်ယောက် အတွက်ပဲ။

Code အရ ကြည့်မယ် ဆိုရင်

public class Customer {
 private String name;
 private List<Account> accounts;

 public Customer(String name) {
  this.account = new ArrayList<Account>();
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public String addAccount(Account account) {
  this.accounts.add(account);
 }
}
public class Account {
 private String accountNumber;
 private double balance;
 private Customer customer;

 public Account(String accountNumber) {
  this.accountNumber = accountNumber;
 }
 public void setCustomer(Customer customer)  {
  this.customer = customer;
 }
 public Customer getCustomer() {
  return this.customer;
 }
 public String getAccountNumber() {
  return this.accountNumber;
 }
 public double getBalance() {
  return this.balance;
 }

}

Aggregation

Aggregation က whole-part relationship အတွက် အသုံးပြုပါတယ်။ Association မှာ contains အနေနဲ့ ပြောခဲ့ပြီးပါပြီ။ Aggregation အနေနဲ့ code အနေနဲ့ အတူတူပါပဲ။ Aggregation က ဘယ်လို နေရာမှာ အသုံးပြုလဲ ဆိုတော့

class Child {}
class Mother {
    List<Child> children;
}

Class Diagram အရ အောက်ပါအတိုင်း ဖော်ပြပါတယ်။

တနည်းအားဖြင့် realtion က အရမ်း strong ဖြစ်တယ်။ Child class ဟာ Mother class မရှိပဲ မရပ်တည်နိုင်ပါဘူး။ အဲဒီလို case တွေမှာ ဆိုရင်တော့ Aggregation ကို အသုံးပြုနိုင်ပါတယ်။

Reflexive Association

Relationship ဟာ same class မှာလည်း အခြင်းခြင်း ဖြစ်နိုင်ပါတယ်။ ဥပမာ ဝန်ထမ်း တွေ အောက်ပါ ဝန်ထမ်းတွေ ရှိနိုင်ပါသေးတယ်။

Code အရ ဆိုရင်

class Employee {
    List<Employee> subordinates;
}

Association Classes

တစ်ခါတစ်လေ class နှစ်ခု ကြားက relation က အခြား class တစ်ခု နဲ့ ချိတ်ဆက်ထားတာ မျိုးရှိပါတယ်။

Student နဲ့ Course က relation ကို Transcripts ကနေ တစ်ဆင့် ရှိပါတယ်။ Code ကို ကြည့်ရအောင်။

class Student {
    Set<Transcript> transcripts = new HashSet<>();
}

class Course {
    Set<Transcript> transcripts = new HashSet<>();
}

class Transcript {
    Student student;
    Course course;
    Date subscriptionDate;

    public Transcript(Student student, Course course, Date subscriptionDate) {
        this.student = student;
        this.course = course;
        this.subscriptionDate = subscriptionDate;
        student.transcripts.add(this);
        course.transcripts.add(this);
    }

    public Course getCourse() {
        return this.course;
    }
}

Dependency

Dependency က တော့ Class တစ်ခုက တစ်ခြား Class တစ်ခုပေါ်မှာ depend လုပ်ထားပါတယ်။ ဥပမာ CoffeeApp က CoffeeMachine ပေါ်မှာ depend ဖြစ်ပါတယ်။ ဒါပေမယ့် CoffeeApp က ကြိုက်သည့် CoffeeMachine ကို ပြောင်းသုံးလို့ရတယ်။ Associate နဲ့ မတူတောကတော့ သူက strong relation မရှိပါဘူး။ တစ်ခြားဟာ တစ်ခု ပြောင်းသုံးပြီးလည်း class က အသုံးပြုလို့ရနေသေးတာပါ။ ဥပမာ

public class CalculateClass {
    public double calculateSquareRoot(double number) {
        return Math.sqrt(number);
    }

    public double calculatePower(double base, double exponent) {
        return Math.pow(base, exponent);
    }
}

CalculateClass က Math class အပေါ်မှာ dependency ရှိနေတာပါ။

Inheritance

UML class diagram မှာ inheritance တွေကို အောက်ကလို မျိုး တြိဂံ ပုံ နဲ့ ဖော်ပြပါတယ်။

Code နဲ့ တွဲ ကြည့်ရအောင်။

public class Bird {
}
public class Duck extends Bird {
}

အထက်ပါ class လိုမျိုးကို အောက်ကလို diagram ဆွဲနိုင်ပါတယ်။

Inheritance ကို သုံးသည့် နေရာတွေ အများကြီး တွေ့နိုင်ပါတယ်။ Manager is Employee ဆိုသည့် relationship တွေ ရှိသည့် နေရာတွေမှာ Inheritance ကို အသုံးပြုနိုင်ပါတယ်။

သတိထားရမှာက Relationship မရှိရင် Inheritance မသုံးသင့်ပါဘူး။

ဥပမာ။ ။ Car နဲ့ Bicycle လိုမျိုးပေါ့။​ ကားမှာလည်း gear ပါတယ်။ Biycle မှာလည်း gear ပါတယ်။ Car မှာလည်း အရောင်ပါတယ်။ model ပါတယ်။ Bicycle လည်း အတူတူပဲ။ properties တွေ တူသလို အချို့ basic function တွေလည်း တူတယ် ဆိုပြီး Inheritance ကို အသုံးပြုလို့ မဖြစ်ပါဘူး။

နောက်ပြီးတော့ Code Reuse တစ်ခု တည်း အတွက်လည်း မသုံးသင့်ပါဘူး။​ Relationship မရှိသည့် School , Professor, Student မှာ ပါသည့် properties တွေ တူတယ် ဆိုပြီး Nameable class ဆိုပြီး ခွဲမထုတ်သင့်ပါဘူး။

Composition

Class နှစ် ခု က IS-A Relation မရှိဘူး။ ဒါပေမယ့် တစ်ခု class နှစ်ခု လုံးက လိုအပ်တယ်။ အဲဒီလို case တွေကို Inheritance အစား compositon ပြောင်းသုံးသင့်ပါတယ်။

ဥပမာ အောက်ပါ class ကို ကြည့်ပါ။

ဒီမှာ ဆိုရင် Person ဆိုသည့် class ကို Inheritance ကို အသုံးပြုထားတာ တွေ့နိုင်ပါတယ်။ တကယ်တန်းက Staff, Student, Professor တို့ဟာ Person ဖြစ်ပေမယ့် Role ပဲ မတူညီကြတာပါ။ Class diagram တွေကို Person ကို Inheritance သုံးမယ့် အစား Composition ပြောင်းသုံးတာ ပိုအဆင်ပြေပါလိမ့်မယ်။

Person object က Role ကို Composition အနေနဲ့ သုံးထားတယ်။ Staff, Student, Professor က Role ကို Inheritance လုပ်ထားတယ်။ ဒါကြောင့် Person နဲ့ Role နဲ့ ကွဲသွားပါတယ်။

public class Person {
    private String name;
    private String address;
    private String phoneNumber;
    private Role role; // Reference to Role

    // getters and setters
}

public abstract class Role {
    // Role specific attributes and methods
}

public class Staff extends Role {
    // Staff specific attributes and methods
}

public class Student extends Role {
    // Student specific attributes and methods
}

public class Professor extends Role {
    // Professor specific attributes and methods
}

Abstract and Interface

OOP မှာ abstract နဲ့ Interface က အရေးကြီးပါတယ်။ အကြမ်းအားဖြင့် abstract နဲ့ interface ကွာခြားချက်ကတော့ abstract က abstract data တွေ အပြင် function တွေပါ ထည့်သွင်းရေးသားနိုင်ပါတယ်။ interface က declration အတွက်ပဲ အသုံးပြုနိုင်ပါတယ်။ ဘယ်အချိန်မှာ abstract, ဘယ် အချိန်မှာ interface တွေ သုံးသင့်သလဲ ဆိုတာကို design pattern ကို လေ့လာသည့် အခါမှာ တွေ့ရပါလိမ့်မယ်။

ဒီ Diagram မှာ ဆိုရင် abstract class ကို သုံးထားပါတယ်။ checkIn နဲ့ checkOut က LibraryItem ထဲမှာ အလုပ်လုပ်မှာ ဖြစ်ပြီး getType ကတော့ abstract function ဖြစ်သည့် အတွက် Book နဲ့ Magazine မှာ တွေ့နိုင်ပါတယ််။ Abstract ရဲ့ connection က Inheritance နဲ့ အတူတူပါပဲ။  Code အနေနဲ့ ကြည့်ရအောင်။

public abstract class LibraryItem {
    private String title;
    private String author;
    private boolean checkOut;

    public abstract String getType();
}

public class Book extends LibraryItem {
    private String ISBN;

    @Override
    public String getType() {
        return "Book";
    }
}

public class Magazine extends LibraryItem {
    private int issueNumber;

    @Override
    public String getType() {
        return "Magazine";
    }
}

Interface ကို ကြည့်ရအောင်။

interface ရဲ့ connection က inheritance နဲ့ မတူပဲ နည်းနည်း ကွာပါတယ်။ dotted ကို သုံးပြီး ရေးဆွဲထားပါတယ်။ ဒီ diagram မှာ Duck က Flyable, Swimable ကို သုံးထားပြီး Penguin ကတော့ Swimable ကိုပဲ အသုံးပြုထားတာကို တွေ့နိုင်ပါတယ်။ Interface က inheritance နဲ့ မတူတာက multiple implement လုပ်လို့ရပါတယ်။ Code ကို ကြည့်ရအောင်။

public interface Flyable {
    void fly();
}

public interface Swimable {
    void swim();
}

public class Duck implements Flyable, Swimable {
    @Override
    public void fly() {
        // Implement fly behavior for Duck
    }

    @Override
    public void swim() {
        // Implement swim behavior for Duck
    }
}

public class Penguin implements Swimable {
    @Override
    public void swim() {
        // Implement swim behavior for Penguin
    }
}

Exercise

Library System တစ်ခုကို UML နဲ့ class diagram ဆွဲကြည့်ပါ။ တစ်ယောက် နဲ့ တစ်ယောက် တူမှာ မဟုတ်ပေမယ့် ကောင်းမွန်သည့် အလေ့အကျင့် တစ်ခု ရှိအောင် ဆွဲကြည့်ပါ။

ကျွန်တော် အကြမ်း ဆွဲထားသည့် design ကတော့ အောက်ပါ အတိုင်း ဖြစ်ပါတယ်။